package com.example.networkprofiler;

import android.os.Bundle;
import android.os.Environment;
import android.app.Activity;
import android.view.Menu;
import org.apache.commons.net.ftp.*;
import com.jcraft.jsch.*;
import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.*;
import java.io.*;
import java.security.SecureRandom;
import android.net.TrafficStats;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import javax.net.ssl.HttpsURLConnection;

import org.apache.commons.io.FileUtils;

public class SpeedTest {
	String type;
	String username;
	String passwd;
	int size;
	SecureRandom randomGenerator;
	InputStream sendStream;
	OutputStream recvStream;
	private final String USER_AGENT = "Mozilla/5.0";
	
	public SpeedTest(String type,String username, String passwd,int size){
		this.type = type;
		this.username = username;
		this.passwd = passwd;
		this.size = size;
		randomGenerator = new SecureRandom();
		byte[] sendByte = randomGenerator.generateSeed(size);
		this.sendStream = new ByteArrayInputStream(sendByte);
		this.recvStream = new ByteArrayOutputStream();
	}
	
	public double[] run(){
		double[] result = new double[2]; 
		System.gc();
		//System.out.println("SpeedTest Starts");
	    
	    String dir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).toString();
	    String fileName = size+".txt";
		String ulFile = dir+"/"+fileName;
		if(type.equals("final")){

			try{
				JSch jsch = new JSch();
				// Build up sftp connection
				Session session = jsch.getSession(username, "sslab02.cs.purdue.edu", 22);			
				UserInfo ui = new MyUserInfo(passwd);
				session.setUserInfo(ui);
				session.connect();
				Channel channel=session.openChannel("sftp");
				channel.connect();
				ChannelSftp c=(ChannelSftp)channel;
				
				// Ping test
				if(InetAddress.getByName("www.cs.purdue.edu").isReachable(1000) == true){					
					// Upload test					
					long tx1 = TrafficStats.getTotalTxBytes();
					long time1 = System.currentTimeMillis();
					c.put(sendStream, "./.www/"+fileName, ChannelSftp.OVERWRITE);
					long time2 = System.currentTimeMillis();
					long tx2 = TrafficStats.getTotalTxBytes();				
					double tp = (tx2-tx1) * 8 / (double)(time2-time1);  // Calculating throughput
					//System.out.println("Uplink Timespan: "+(time2-time1)+" ms Data Transfered: "+(tx2-tx1)+ " bytes");
					result[0] = tp;
					//System.out.println("Uplink Throughput: "+tp+" kbps");
					sendStream.close();
					c.quit();
					
					// Download test
					String dest= Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).toString()+"/"+fileName;
					String url = "http://www.cs.purdue.edu/homes/jin72/"+fileName;
					URL obj = new URL(url);
					File destFile = new File(dest);
					long rx1 = TrafficStats.getTotalRxBytes();
					time1 = System.currentTimeMillis();
					FileUtils.copyURLToFile(obj, destFile);
					time2 = System.currentTimeMillis();
					long rx2 = TrafficStats.getTotalRxBytes();				
					tp = (rx2-rx1) * 8 / (double)(time2-time1);  // Calculating throughput
					// System.out.println("Downlink Timespan: "+(time2-time1)+" ms Data Transfered: "+(rx2-rx1)+ " bytes");
					result[1] = tp;
					//System.out.println("Downlink Throughput: "+tp+" kbps");
				}
				else{
					System.err.println("Unreachable address");
				}
			}catch(Exception e){
				e.printStackTrace();
			}
		}
		else if(type.equals("ftp")){
			FTPClient ftp = new FTPClient();
			try{
				ftp.connect("ftp2.us.freebsd.org");
				ftp.login("anonymous", "1234");
				ftp.setFileType(FTP.BINARY_FILE_TYPE);
		        ftp.enterLocalPassiveMode();
		        //InputStream input = new FileInputStream(new File(ulFile));
		        long tx1 = TrafficStats.getTotalTxBytes();
		        long time1 = System.currentTimeMillis();
		        ftp.storeFile("",sendStream);
		        long time2 = System.currentTimeMillis();
		        long tx2 = TrafficStats.getTotalTxBytes();
				System.out.println("Uplink Timespan: "+(time2-time1)+" ms Data Transferred: "+(tx2-tx1)+ " bytes");
				double tp = (tx2-tx1) * 8 / (time2-time1); 
				result[0] = tp;
				System.out.println("Uplink Throughput: "+tp+" kbps");
				
				System.gc();
				
				//FileOutputStream fos = new FileOutputStream(dir+"/filelist.gz");
				long rx1 = TrafficStats.getTotalRxBytes();
			 	time1 = System.currentTimeMillis();
			    ftp.retrieveFile("CentOS/filelist.gz", recvStream);
			    time2 = System.currentTimeMillis();
			    long rx2 = TrafficStats.getTotalRxBytes();
				System.out.println("Downlink Timespan: "+(time2-time1)+" ms Data Transferred: "+(rx2-rx1)+" bytes");
				tp =  (rx2-rx1) * 8 / (time2-time1); 
				result[1] = tp;
				System.out.println("Downlink Throughput: "+tp+" kbps");
		        ftp.logout();
		        ftp.disconnect();
			}catch(Exception e){
				e.printStackTrace();
			}
		}
		else if(type.equals("sftp")){
			
			
			try{
				JSch jsch = new JSch();
				// Build up connection
				Session session = jsch.getSession(username, "sslab02.cs.purdue.edu", 22);
				//System.out.println(System.getProperty("user.dir"));
							
				UserInfo ui = new MyUserInfo(passwd);
				session.setUserInfo(ui);
				session.connect();
				Channel channel=session.openChannel("sftp");
				channel.connect();
				ChannelSftp c=(ChannelSftp)channel;
				
				// Upload test
				if(InetAddress.getByName("www.cs.purdue.edu").isReachable(1000) == true){					
					
					// Upload test
					long tx1 = TrafficStats.getTotalTxBytes();
					long time1 = System.currentTimeMillis();
					c.put(sendStream, "./.www/"+fileName, ChannelSftp.OVERWRITE);
					long time2 = System.currentTimeMillis();
					long tx2 = TrafficStats.getTotalTxBytes();				
					double tp = (tx2-tx1) * 8 / (time2-time1); 
					//System.out.println("Uplink Timespan: "+(time2-time1)+" ms Data Transfered: "+(tx2-tx1)+ " bytes");
					result[0] = tp;
					
					sendStream.close();
				
					// Download test
					
								
					//System.out.println("Downlink Starts");
					long rx1 = TrafficStats.getTotalRxBytes();	
					time1 = System.currentTimeMillis();			
					c.get("./.www/"+fileName,recvStream);
					time2 = System.currentTimeMillis();
					long rx2 = TrafficStats.getTotalRxBytes();
					//System.out.println("Downlink Timespan: "+(time2-time1)+" ms Data Transfered: "+(rx2-rx1)+" bytes");
					tp = (rx2-rx1) * 8 / (time2-time1); 
					result[1] = tp;
					//System.out.println("Downlink Throughput: "+tp+" kbps");
					recvStream.close();
									
				}
				else{
					System.err.println("Unreachable address");
				}
				c.quit();
				session.disconnect();
			}catch(Exception e){
				e.printStackTrace();
			}
			
			
		}
		else if(type.equals("http")){
			String url = "http://www.cs.purdue.edu/homes/jin72/1mb.txt";
			try{
				URL obj = new URL(url);
				HttpURLConnection con = (HttpURLConnection) obj.openConnection();
		 
				// optional default is GET
				con.setRequestMethod("GET");
		 
				//add request header
				con.setRequestProperty("User-Agent", USER_AGENT);
				int responseCode = con.getResponseCode();
		 
				if(InetAddress.getByName("www.cs.purdue.edu").isReachable(1000) == false){
					System.err.println("Unreachable address");
				}
				System.gc();
				System.out.println("Downlink Starts");
				String inputLine;
				StringBuffer response = new StringBuffer();
				BufferedReader in;
				long rx1 = TrafficStats.getTotalRxBytes();
				long time1 = System.currentTimeMillis();
				in = new BufferedReader(
				        new InputStreamReader(con.getInputStream()));		 
				while ((inputLine = in.readLine()) != null) {
					response.append(inputLine);
				}
				long rx2 = TrafficStats.getTotalRxBytes();
				long time2 = System.currentTimeMillis();
				System.out.println("Downlink Timespan: "+(time2-time1)+" ms Data Transfered: "+(rx2-rx1)+" bytes");
				long tp = (rx2-rx1) * 8 / (time2-time1); 
				result[0] = 0;
				result[1] = tp;
				System.out.println("Downlink Throughput: "+tp+" kbps");
				
				in.close();
			}catch(Exception e){
				e.printStackTrace();
			}
		}
	
		//System.out.println("SpeedTest Ends");
		return result;
	}
	
	protected void CreateRandomFile(String path, String name, int size){
		File file = new File(path,name);
		
		try{
			if(file.getParentFile().mkdir()){
				System.out.println("Created parent directory.");
			}
			if(file.exists()){
				file.delete();
			}
			if(!file.createNewFile()){
				System.err.println("File creating failed.");
			}
		
			RandomAccessFile raf = new RandomAccessFile(file,"rw");
			raf.setLength(size);
			raf.close();
			
		}catch(Exception e){
			e.printStackTrace();
		}
		
		//System.out.println("File is created");
		
	}
	
}


